<template>
  <el-card>
    <template #header>
      <div class="cardHeader">
        <div>
          当前语言：{{language}}
        </div>
        <div>
          <el-button @click="formatterCode">格式化</el-button>
        </div>
        <div>
          <span>设置主题</span>
          <el-select v-model="theme" @change="setOptions">
            <el-option
              :value="item"
              v-for="item in themeList"
              :key="item"
            ></el-option>
          </el-select>
        </div>
      </div>
    </template>
    <div ref="codeEditRef">
    </div>
  </el-card>
</template>

<script>
import ace from "ace-builds";
import "ace-builds/src-noconflict/ext-language_tools"; // 启动提示菜单
import "ace-builds/src-noconflict/ext-emmet";
import {themeList} from "./config";
ace.config.set('workerPath','node_modules/ace-builds/src-noconflict') // 设置worker基础路径
ace.require('ace/ext/language_tools') // 这个是自定义补全
ace.require('ace/ext/ext-emmet')
export default {
  name:"CodeEdit",
  model:{
    event:'update:value',
    prop:'value'
  },
  props:{
    value:{
      type:String,
      default:''
    },
    // 外部传入的语法类型
    language: {
      type: String,
      default: "json",
    },
  },
  watch:{
    value(newProps){
      if(this.codeEdit){
        //解决光标移动问题
        const position = this.codeEdit.getCursorPosition();
        this.codeEdit.getSession().setValue(newProps);
        this.codeEdit.clearSelection();
        this.codeEdit.moveCursorToPosition(position);
      }
    },
    language(){
      this.setOptions()
    }
  },
  data(){
    return{
      codeEdit:null,
      themeList,
      theme: "gruvbox_dark_hard"
    }
  },
  computed:{
    importLanguage(){
      return 'mode-'+this.language
    },
    importTheme(){
      return 'theme-'+this.theme
    },
  },
  mounted() {
    this.codeEdit = ace.edit(this.$refs.codeEditRef,{
      tabSize: 2,
      maxLines: 25,
      minLines: 25,
      showPrintMargin: false,
      fontSize: 14,
    })
    this.setOptions()
    this.codeEdit.getSession().setUseWrapMode(true);
    this.codeEdit.on("change",()=>{
      this.$emit('update:value',this.codeEdit.getValue())
    })
    //快捷键
    this.codeEdit.commands.addCommand({
      name: 'formatter',
      bindKey: { win: 'Ctrl-Shift-F', mac: 'Command-Shift-F' },
      exec: () => this.formatterCode()
    })
    this.codeEdit.setValue(this.value);
  },
  methods:{
    setOptions(){
      Promise.all([
        import('ace-builds/src-noconflict/'+this.importLanguage),
        import('ace-builds/src-noconflict/snippets/'+this.language),
        import('ace-builds/src-noconflict/'+this.importTheme),
      ]).then(()=>{
        this.codeEdit.setOptions({
          theme: "ace/theme/" + (this.theme),
          mode: "ace/mode/" + (this.language),
          wrap: true,
          enableSnippets: true,
          enableLiveAutocompletion: true,
          enableBasicAutocompletion: true,
        })
      })
    },
    formatterCode() {
      this.$emit('formatter', this.codeEdit)
    }
  },
  beforeDestroy() {
    if(this.codeEdit){
      this.codeEdit.destroy()
    }
  }
}
</script>

<style scoped lang="scss">
.cardHeader{
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>
